package com.corechina.apex_osswords.common.config.oauth2;


import com.corechina.apex_osswords.common.JwtUtil;
import com.corechina.apex_osswords.domain.dao.CoreWeiXinMapper;
import com.corechina.apex_osswords.domain.entity.SysUserToken;
import com.corechina.apex_osswords.domain.vo.CoreWeiXinUserInfoVo;
import com.corechina.apex_osswords.domain.vo.SysUserForTokenVo;
import com.corechina.apex_osswords.service.IShiroService;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import java.util.Set;

/**
 * 认证
 *
 * @author Styx
 */
@Slf4j
@Component
public class OAuth2Realm extends AuthorizingRealm {
    @Autowired
    private IShiroService iShiroService;

    @Autowired
    private CoreWeiXinMapper coreWeiXinMapper;

    @Override
    public boolean supports(AuthenticationToken token) {
        return token instanceof OAuth2Token;
    }

    /**
     * 授权(验证权限时调用)
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        SysUserForTokenVo sysUserForTokenVo = (SysUserForTokenVo) principals.getPrimaryPrincipal();
        Integer userId = sysUserForTokenVo.getId();

//        //用户权限列表
        Set<String> permsSet = iShiroService.getUserPermissions(userId);

        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        info.setStringPermissions(permsSet);
        return info;
    }

    /**
     * 认证(登录时调用)
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        SimpleAuthenticationInfo info = null;
        String accessToken = (String) token.getPrincipal();
        //根据accessToken，查询用户信息
        SysUserToken sysUserToken = iShiroService.getByToken(accessToken);
        if(sysUserToken == null){
            throw new IncorrectCredentialsException("token失效，请重新登录");
        }
        if (sysUserToken.getLoginType() == 0) {
            //token失效
            if ( !JwtUtil.verify(sysUserToken) || sysUserToken.getExpireTime().getTime() < System.currentTimeMillis()) {
                throw new IncorrectCredentialsException("token失效，请重新登录");
            }
            //查询用户信息
            SysUserForTokenVo sysUserForTokenVo = iShiroService.getUser(sysUserToken.getUserId());

            //账号锁定
            if (sysUserForTokenVo.getEnabled() == 0) {
                log.error("账号已被锁定");
                throw new LockedAccountException("账号已被锁定,请联系管理员");
            }
            info = new SimpleAuthenticationInfo(sysUserForTokenVo, accessToken, getName());
        } else if (sysUserToken.getLoginType().equals(1)) {
            //token失效
            if (!JwtUtil.verify(sysUserToken) || sysUserToken.getExpireTime().getTime() < System.currentTimeMillis()) {
                throw new IncorrectCredentialsException("token失效");
            }
            //查询用户信息
            CoreWeiXinUserInfoVo coreWeiXinUserInfoVo = coreWeiXinMapper.getWeiXinUserInfo(sysUserToken.getUserId(),sysUserToken.getLoginType());
            if (coreWeiXinUserInfoVo == null || coreWeiXinUserInfoVo.getForbidden().equals(1)) {
                throw new LockedAccountException("该账号已禁用,请先联系管理员");
            }
            info = new SimpleAuthenticationInfo(coreWeiXinUserInfoVo, accessToken, getName());
        }
        return info;
    }

}
